package com.cans.security.browser.filter;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.cans.security.browser.service.api.ICustomUserService;
import org.springframework.http.*;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * description: 通过重写filter实现单点的登录
 * @author cans
 * @date 2017/11/18
 */
public class SsoAuthenticationFilter extends AbstractAuthenticationProcessingFilter {


    public SsoAuthenticationFilter() {
        super("/sso/ticket");
    }

    /**
     * SSO验证票据地址
     */
    private String ssoServerUrl;
    /**
     * 用户操作服务
     */
    private ICustomUserService customUserService;

    public void setCustomUserService(ICustomUserService customUserService) {
        this.customUserService = customUserService;
    }

    public void setSsoServerUrl(String ssoServerUrl) {
        this.ssoServerUrl = ssoServerUrl;
    }

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {

        String ticket = request.getParameter("ticket");


        if(!StringUtils.isEmpty(ticket)){

            JSONObject user = getUser(ticket);
            String username = user.getString("username");

            customUserService.checkAndSave(username);

            UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, 1);

            return this.getAuthenticationManager().authenticate(authRequest);
        }
        return null;
    }

    /**
     * 向指定URL发送GET方法的请求
     * 通过ticket获取用户信息
     *
     * @param ticket
     */
    public JSONObject getUser(String ticket){
        RestTemplate restTemplate=new RestTemplate();
        String url = ssoServerUrl + "sso/ticket?ticket=" + ticket;
        /* 注意：必须 http、https……开头，不然报错，浏览器地址栏不加 http 之类不出错是因为浏览器自动帮你补全了 */
        HttpHeaders headers = new HttpHeaders();
        /* 这个对象有add()方法，可往请求头存入信息 */
        headers.setContentType(MediaType.APPLICATION_XML);
        /* 解决中文乱码的关键 , 还有更深层次的问题 关系到 StringHttpMessageConverter，先占位，以后补全*/
        String body = "ticket=" + ticket;
        HttpEntity<String> entity = new HttpEntity<>(body, headers);
        /* body是Http消息体例如json串 */
        ResponseEntity<String> exchange = restTemplate.exchange(url, HttpMethod.GET, entity, String.class);

        JSONObject jsonObject = JSON.parseObject(exchange.getBody());

        return jsonObject.getJSONObject("data");
    }
}
